﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Newtonsoft.Json;
using System.ComponentModel;
using System.Windows.Media.Imaging;
using System.Windows.Documents;
using System.Windows.Controls;
using System.Text.RegularExpressions;
using System.Windows.Media;
using System.IO;
using System.Collections;

namespace WasaWasa
{
    public class StatusClass : INotifyPropertyChanged
    {
        private const string UriPrefixUserPage = "http://wassr.jp/user/";

        static Regex atmarkRegex = new Regex(@"@(?<userId>[0-9a-zA-Z_]+)");
        static Regex urlRegex = new Regex(@"http://[\x21-\x7F]+");
        static Regex pictgramRegex = new Regex(@"[\uE001-\uE05A\uE101-\uE15A\uE201-\uE257\uE301-\uE34D\uE401-\uE5DF\uE63E-\uE757\uEA80-\uEB88\uEC40-\uECFC\uED40-\uED80\uEF4B]");

        [JsonPropertyAttribute("user_login_id")]
        public string _UserLoginId { get; set; }
        [JsonPropertyAttribute("areacode")]
        public string Areacode { get; set; }
        [JsonPropertyAttribute("photo_thumbnail_url")]
        public string PhotoThumbnailUrl { get; set; }
        [JsonPropertyAttribute("html")]
        public string Html { get; set; }
        [JsonPropertyAttribute("reply_status_url")]
        public string ReplyStatusUrl { get; set; }
        [JsonPropertyAttribute("text")]
        public string _Text { get; set; }
        [JsonPropertyAttribute("id")]
        public long Id { get; set; }
        [JsonPropertyAttribute("link")]
        public string Link { get; set; }
        [JsonPropertyAttribute("reply_user_login_id")]
        public string ReplyUserLoginId { get; set; }
        [JsonPropertyAttribute("epoch")]
        public long Epoch { get; set; }
        [JsonPropertyAttribute("rid")]
        public string Rid { get; set; }
        [JsonPropertyAttribute("photo_url")]
        public string PhotoUrl { get; set; }
        [JsonPropertyAttribute("reply_message")]
        public string ReplyMessage { get; set; }
        [JsonPropertyAttribute("reply_user_nick")]
        public string ReplyUserNick { get; set; }
        [JsonPropertyAttribute("slurl")]
        public string SLUrl { get; set; }
        [JsonPropertyAttribute("areaname")]
        public string Areaname { get; set; }
        [JsonPropertyAttribute("user")]
        public UserClass User { get; set; }

        [JsonProperty("body")]
        public string _Body { get; set; }
        [JsonProperty("created_on")]
        public string _CreatedOn { get; set; }

        [JsonProperty("favorites")]
        public ArrayList Favorites { get; set; }

        [JsonProperty("channel")]
        public ChannelClass Channnel { get; set; }

        private bool readed;
        public bool IsReaded
        {
            get { return readed; }
            set
            {
                readed = value;
                PropertyChanged(this, new PropertyChangedEventArgs("IsReaded"));
            }
        }
        public string LoginId
        {
            get { return _UserLoginId != null ? _UserLoginId : User._LoginId; }
        }
        public string Nick
        {
            get { return User._ScreenName != null ? User._ScreenName : User._Nick; }
        }
        public string Text
        {
            get { return _Text != null ? _Text : _Body; }
        }
        public DateTime DateTime
        {
            get
            {
                return _CreatedOn == null ?
                    new DateTime(1970, 1, 1).AddSeconds(Epoch).ToLocalTime() :
                    DateTime.Parse(_CreatedOn);
            }
        }
        public BitmapImage ProfileImage
        {
            get { return UserImageCache.Default.GetProfilePicture(LoginId); }
        }
        public string UserLink
        {
            get { return LoginId != null ? UriPrefixUserPage + LoginId : null; }
        }
        public string ReplyUserLink
        {
            get { return ReplyUserLoginId != null ? UriPrefixUserPage + ReplyUserLoginId : null; }
        }

        private static ImageSourceConverter imageSourceConverter = new ImageSourceConverter();

        public class UserClass
        {
            [JsonPropertyAttribute("protected")]
            public string Protected { get; set; }
            [JsonPropertyAttribute("profile_image_url")]
            public string ProfileImageUrl { get; set; }
            [JsonPropertyAttribute("screen_name")]
            public string _ScreenName { get; set; }

            [JsonProperty("profimg_last_updated_at")]
            public long ProfimgLastUpdatedAt { get; set; }
            [JsonProperty("nick")]
            public string _Nick { get; set; }
            [JsonProperty("login_id")]
            public string _LoginId { get; set; }
        }

        public class ChannelClass
        {
            [JsonProperty("title")]
            public String Title { get; set; }
            [JsonProperty("name_en")]
            public String NameEn { get; set; }
            [JsonProperty("onmitsu_fg")]
            public String OnmitsuFg { get; set; }
        }

        public static IEnumerable<Inline> GenerateInlines(string text)
        {
            int ptr = 0;
            while (ptr < text.Length)
            {
                Match m1 = atmarkRegex.Match(text, ptr);
                Match m2 = urlRegex.Match(text, ptr);
                Match m3 = pictgramRegex.Match(text, ptr);
                Match m =
                    m1.Success && (!m2.Success && !m3.Success) ? m1 :
                    m2.Success && (!m1.Success && !m3.Success) ? m2 :
                    m3.Success && (!m1.Success && !m2.Success) ? m3 :
                    !m1.Success && !m2.Success && !m3.Success ? null :
                    (m1.Success && (!m2.Success || m1.Index < m2.Index)) && (m1.Success && (!m3.Success || m1.Index < m3.Index)) ? m1 :
                    (m2.Success && (!m1.Success || m2.Index < m1.Index)) && (m2.Success && (!m3.Success || m2.Index < m3.Index)) ? m2 : m3;
                if (m == null)
                {
                    yield return new Run(text.Substring(ptr));
                    break;
                }
                yield return new Run(text.Substring(ptr, m.Index - ptr));
                if (m == m1 || m == m2)
                {
                    Hyperlink link = new Hyperlink()
                    {
                        NavigateUri = new Uri(m1.Success ?
                            (UriPrefixUserPage + m.Groups["userId"]) : m.Value),
                    };
                    link.Inlines.Add(m.Value);
                    yield return link;
                }
                else
                {
                    while (true)
                    {
                        BitmapImage img = null;
                        try
                        {
                            img = new BitmapImage(new Uri(string.Format("pack://application:,,,/WasaWasa.Pictograms;component/{0:X}.gif", (int)m.Value[0])));
                        }
                        catch(IOException ex)
                        {
                            ExceptionWindow.Show(ex);
                            break;
                        }
                        
                        yield return new InlineUIContainer(new Image()
                        {
                            Source = img,
                            Width = img.PixelWidth,
                            Height = img.PixelHeight,
                        });
                        break;
                    }
                }

                ptr += (m.Index - ptr) + m.Length;
            }
        }

        #region INotifyPropertyChanged メンバ
        public event PropertyChangedEventHandler PropertyChanged;
        #endregion
    }
}
